import os
import subprocess

import psutil
import redis
from config import get_config
from config import init_config


class RedisUtil(object):

    def __init__(self, config_path=None):
        if not config_path:
            config_path = 'config.ini'
        else:
            print("config_path:", config_path)
            config_path = config_path
        init_config(config_path)
        self.host = get_config(config_path, 'redis', 'host')
        self.port = get_config(config_path, 'redis', 'port')
        self.password = get_config(config_path, 'redis', 'password')
        self.redis_path = get_config(config_path, 'redis', 'redispath')

    def check_port(self, port):
        """
        Check if the port is in use
        """
        for conn in psutil.net_connections(kind='inet'):
            if conn.laddr.port == port and conn.status == psutil.CONN_LISTEN:
                return True

    def test_redis_connection(self):
        try:
            if self.password:
                redis_client = redis.Redis(host=self.host, port=int(self.port), socket_timeout=3,
                                           password=self.password)
                if redis_client.ping():
                    print("Redis connection successful")
                    print("Redis password set to 'password: %s'" % self.password)
                    return True
            else:
                redis_client = redis.Redis(host=self.host, port=int(self.port), socket_timeout=3)
                if redis_client.ping():
                    print("Redis connection successful")
                    print("Redis password mot set  'password'")
                    return True
        except redis.exceptions.ConnectionError:
            redis_client_temp = redis.Redis(host=self.host, port=int(self.port), password=self.password,
                                            socket_timeout=3)
            try:
                redis_client_temp.ping()
                print("Redis connection successful")
                return True
            except redis.exceptions.ConnectionError:
                print("Redis connection failed,尝试启动redis服务......")
                return False

    def start_redis_server(self):
        try:
            path = os.path.join(self.redis_path)
            redis_server = os.path.join(path, "redis-server.exe")
            redis_conf = os.path.join(path, "redis.windows.conf")
            try:
                if self.check_port(self.port):
                    print(f"Redis port {self.port} is already in use, please check if Redis is already running.")

                    return False
                subprocess.Popen(["cmd", "/c", f"start", "cmd", "/k", redis_server, redis_conf], shell=True,
                                 stdout=subprocess.PIPE, stderr=subprocess.PIPE)

                redis_client_temp_1 = redis.Redis(host=self.host, port=int(self.port), socket_timeout=3)
                try:
                    redis_client_temp_1.ping()
                    redis_client_temp_1.config_set('requirepass', self.password)
                    print("Redis started and connection successful")
                    return True
                except Exception as e:
                    redis_client_temp_1 = redis.Redis(host=self.host, port=int(self.port), socket_timeout=3,
                                                      password=self.password)
                    if redis_client_temp_1.ping():
                        return True
                    print("Redis  connection failed", e)
                    return False
            except Exception as e:
                print(e)
                return False
        except Exception as e:
            print(e)
            return False


if __name__ == '__main__':
    test = RedisUtil('config.ini')
    test.test_redis_connection()
